import EventEmitter from "../eventemitter/EventEmitter";

const Emit_Change = 'Emit_Change'

export default class ValueWatcher<T> extends EventEmitter {

    private readonly _origin: T;
    private _value: T;

    constructor(value: T) {
        super()
        this._value = value;
        this._origin = value;
    }

    get value(): T {
        return this._value
    }

    get origin(): T {
        return this._origin;
    }

    reset() {
        if (this.origin === this.value) return;
        this.change(this.origin);
    }

    change(v: T) {
        if (this._value === v) return;
        const pre = this._value;
        this._value = v;
        this.emit(Emit_Change, this, this._value, pre);
    }

    isChange() {
        return this._value !== this._origin;
    }

    listenerChange(call: (watch: ValueWatcher<T>, curr: T, pre: T) => void) {
        this.on(Emit_Change, call, this)
        return () => {
            this.off(Emit_Change, call, this);
        };
    }

    listenerChangeOnce(call: (watch: ValueWatcher<T>, curr: T, pre: T) => void) {
        this.once(Emit_Change, call, this)
        return () => {
            this.off(Emit_Change, call, this, true);
        };
    }
}